package tina.classparsing;

public class TinaConstantPool {
    private TinaConstantPoolEntry[] cp;

    public TinaConstantPool(int cp_count) {
        cp = new TinaConstantPoolEntry[cp_count];
    }

    public void setElementAt(TinaConstantPoolEntry e, int idx) {
        cp[idx] = e;
    }

    public int length() {
        return cp.length;
    }

    public TinaConstantPoolEntry elementAt(int idx) throws TinaConstantPoolException {
        if(isValidIndex(idx))
            return cp[idx];
        else throw new TinaConstantPoolException("invalid index in constant pool : "+idx);
    }

    public String getIndirectName(int idx) throws TinaConstantPoolException {
        if (isValidIndex(idx)
            && (cp[idx].getType()==TinaConstantPoolEntry.CONSTANT_Class
                ||cp[idx].getType()==TinaConstantPoolEntry.CONSTANT_String)) {
            int nameidx = (Integer)cp[idx].getFirstValue();
            if (isValidIndex(nameidx) 
                && cp[nameidx].getType()==TinaConstantPoolEntry.CONSTANT_Utf8)
                return cp[nameidx].getFirstValue().toString();
            else throw new TinaConstantPoolException("can't read CONSTANT_Utf8 at index "+nameidx);
        } else throw new TinaConstantPoolException("can't read CONSTANT_Class or CONSTANT_String at index "+idx);
    }

    public String getDirectName(int idx) throws TinaConstantPoolException {
        if (isValidIndex(idx) 
            && cp[idx].getType()==TinaConstantPoolEntry.CONSTANT_Utf8) 
            return cp[idx].getFirstValue().toString();
        else throw new TinaConstantPoolException("can't read CONSTANT_Utf8 at index "+idx);
    }

    public String getValue(int idx) throws TinaConstantPoolException {
        if (isValidIndex(idx) 
            && (cp[idx].getType()==TinaConstantPoolEntry.CONSTANT_Integer
                ||cp[idx].getType()==TinaConstantPoolEntry.CONSTANT_Double
                ||cp[idx].getType()==TinaConstantPoolEntry.CONSTANT_Float
                ||cp[idx].getType()==TinaConstantPoolEntry.CONSTANT_Long
                ||cp[idx].getType()==TinaConstantPoolEntry.CONSTANT_Utf8))
            return String.valueOf(cp[idx].getFirstValue());
        else throw new TinaConstantPoolException("can't read constant at index "+idx);
    }

    public boolean isValidIndex(int idx) {
        if (idx<=0 || idx>=cp.length)
            return false;
        else if (cp[idx-1]!=null 
                 && (cp[idx-1].getType()==TinaConstantPoolEntry.CONSTANT_Long 
                     || cp[idx-1].getType()==TinaConstantPoolEntry.CONSTANT_Double))
            return false;
        else
            return true;
    }
}